<?php

/**
 * Framework_DB_DaoRelation
 *
 * @author Application Support Group
 * @copyright University of Georgia
 * @package BAMF
 * @see Framework_DB_DaoNode
 * @filesource
*/


abstract class Framework_DB_DaoRelation extends Framework_DB_DaoNode {

	const DAO_TYPE = 'DaoRelation' ;
	
	public function __construct( $schemaFile ) {
		parent::__construct( $schemaFile ) ;


	}

	/**
	* SQL insert data from object
	*/
	public function create( $validate=true ) {

		$_output = false ;
		$isValid = false ;
		$sqlValues = array() ; 

		if( $validate ) {// make sure object has valid data
			$validation = $this->isValid() ;

			if( !Framework_ErrorHandler::isError( $validation, __METHOD__."::".__LINE__ )) {
				$isValid = true ;
			} else {
				$_output = $validation ;
			}

		} else {// just do the SQL
			$isValid = true ;
		}

		if( $isValid ) {
			// assemble key/value pairs
			$fieldArray = array() ;
			$valueArray = array() ;
			$sqlValues = array() ;
			foreach( $this->_attributes as $key => $value ) {
				$fieldArray[] = $key ;
				$valueArray[] = "?" ;
				if(!empty($value) || is_numeric($value)) {
					$sqlValues[] = $value;
				} else {
					//Some datatypes don't respond well to getting an empty string for the default value.
					if($this->_schema["field_default_values"][$key] === '' && 
							in_array($this->_schema["field_definitions"][$key], $this->_NULL_TYPES)) {
						//so we'll use null instead
						$sqlValues[] = null;
					} else {
						$sqlValues[] = $this->_schema["field_default_values"][$key] ;
					}
				}
			}
	
			$fieldList = "(" . implode( ",", $fieldArray ) . ")" ;
			$valueList = "(" . implode( ",", $valueArray ) . ")" ;
			$sqlStatement = "INSERT INTO {$this->_DB_TABLE} $fieldList VALUES $valueList" ;
			$preparedStmt = $this->db->prepare( $sqlStatement ) ;
			if(Framework_ErrorHandler::isError($preparedStmt)) {
				return $preparedStmt;
			}
			$result = $preparedStmt->execute( $sqlValues ) ;
			$preparedStmt->free() ;

			if( Framework_ErrorHandler::isError( $result, __METHOD__."::".__LINE__ )) {
				$_output = $result ;
			} else {
				$_output = true ;
			}
		}// end if
		
		return $_output ;

	}// end create


	/**
	* Do an SQSL update using the object's data
	*/
	public function update( $refresh=true, $validate=true ) {

		$_output = false ;
		$isValid = false ;
		$sqlValues = array() ; // just to see some sql

		if( $validate ) {// make sure object has valid data
			$validation = $this->isValid() ;

			if( !Framework_ErrorHandler::isError( $validation, __METHOD__."::".__LINE__ )) {
				$isValid = true ;
			} else {
				$_output = $validation ;
			}

		} else {// just do the SQL
			$isValid = true ;
		}

		if( $isValid ) {
			// assemble key/value pairs
			$setValueArray = array() ;
			$whereValueArray = array() ;
			$sqlValues = array() ;
			foreach( $this->_attributes as $key => $value ) {
				$setValueArray[] = "$key=?" ;
				if( $value === '' && in_array($this->_schema["field_definitions"][$key],
							$this->_NULL_TYPES)) {
					$sqlValues[] = null;
				} else {
					$sqlValues[] = $value ;
				}
				if($this->_schema['field_definitions'][$key] == DB_DATATYPE_KEY) {
					$whereValueArray[] = "$key={$this->$key}";
				}
			}
	
			$setValueList = implode( ",", $setValueArray );
			$whereValueList = implode( " AND ", $whereValueArray );
			$sqlStatement = "UPDATE {$this->_DB_TABLE} SET $setValueList WHERE $whereValueList";
			$preparedStmt = $this->db->prepare( $sqlStatement ) ;
			if(Framework_ErrorHandler::isError($preparedStmt)) {
				return $preparedStmt;
			}
			$result = $preparedStmt->execute( $sqlValues ) ;
			$preparedStmt->free() ;

	
			if( Framework_ErrorHandler::isError( $result, __METHOD__."::".__LINE__ )) {
				$_output = $result ;
			} else {
				if( $refresh ) { $_output = $this->refresh() ; }
				else { $_output = true ; }
			}
		}// end if
	
		return $_output ;

	}// end update

	/**
	* Assemble the SQL to remove this object's record
	* This should override the method set in Framework_DB_DaoNode.
	 *
	 * @param	$parameterized	If true, returns an array with a parameterized query at key "sql" and the values at key "values", else returns a string. Defalts to false.
	*/
	public function getRemoveStatement($parameterized = false) {
		$whereFragment = "WHERE" ;
		$whereValues = array();
		$fieldCount = count( $this->_schema['fields'] ) ;

		for( $i=0; $i<$fieldCount; $i++ ) {
			$field = $this->_schema['fields'][$i] ;
			$fieldValue = ($parameterized ? '?' : $this->$field);
			if( $this->_schema['field_definitions'][$field] == DB_DATATYPE_VIRTUAL ) {
				continue;
			}
			
			if( $whereFragment != 'WHERE' ) {
				$whereFragment .= "AND" ;
			}
			
			switch( $this->db->dsn['dbsyntax'] ) {
				case DSN_OCI :
					if( $this->_schema['field_definitions'][$field] == DB_DATATYPE_DATETIME ) {
						if($parameterized) {
							$whereFragment .= " $field = TO_DATE( ? , ?) " ;
						} else {
							$whereFragment .= " $field = TO_DATE( '$fieldValue', '" . OCI_DATE_FORMAT_STRING . "' ) " ;
						}
						$whereValues[] = $this->$field;
						$whereValues[] = $formatString;
					} else {
						$whereFragment .= " $field = $fieldValue " ;
						$whereValues[] = $this->$field;
					}
					break ;
				case DSN_MSSQL :
				case DSN_MYSQL :
				default :
					if( !$parameterized && in_array($this->_schema['field_definitions'][$field], array(
							DB_DATATYPE_DATETIME, DB_DATATYPE_STRING_BASIC, DB_DATATYPE_STRING_EMAIL,
							DB_DATATYPE_STRING_PHONE, DB_DATATYPE_STRING_URI, DB_DATATYPE_STRING_XML,
							DB_DATATYPE_TIME))) {
						$whereFragment .= " $field = '$fieldValue' " ;
					} else {
						$whereFragment .= " $field = $fieldValue " ;
					}
					$whereValues[] = $this->$field;
			}
		}

		$sql = "DELETE FROM ".$this->_DB_TABLE." ".$whereFragment ;
		if($parameterized) {
			return array('sql' => $sql, 'values' => $whereValues);
		} else {
			return $sql ;
		}
	}

	/**
	* delete the relation
	*/
	public function remove() {
		$_output = false ;
		$remove = $this->getRemoveStatement(true);
		$sql = $remove['sql'];
		$values = $remove['values'];
		$preparedStmt = $this->db->prepare( $sql ) ;
		if(Framework_ErrorHandler::isError($preparedStmt)) {
			return $preparedStmt;
		}
		$result = $preparedStmt->execute( $values ) ;
		$preparedStmt->free() ;
		
		if( Framework_ErrorHandler::isError( $result, __METHOD__."::".__LINE__ )) { $_output = $result ; }
		else { $_output = true ; }

		return $_output ;
	}




	public function __destruct() {
		parent::__destruct() ;
	}

}

?>
